package com.nightonke.boommenu;

import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.app.Context;
import ohos.agp.components.element.PixelMapElement;
import ohos.agp.components.StackLayout;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.render.Texture;
import ohos.agp.utils.Color;
import ohos.agp.utils.RectFloat;
import ohos.media.image.common.PixelFormat;
import ohos.media.image.common.Size;
import ohos.media.image.PixelMap;

/**
 * Created by Weiping Huang at 19:09 on 16/11/6
 * For Personal Open Source
 * Contact me at 2584541288@qq.com or nightonke@outlook.com
 */

public class BMBShadow extends StackLayout {

    private boolean shadowEffect = true;
    private int shadowOffsetX;
    private int shadowOffsetY;
    private int shadowRadius;
    private int shadowCornerRadius;
    private Color shadowColor;

    public BMBShadow(Context context) {
        super(context);
        init();
    }

    public BMBShadow(Context context, AttrSet attrs) {
        super(context, attrs);
        init();
    }

    public BMBShadow(Context context, AttrSet attrs, String defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init()
    {
        this.setBindStateChangedListener(new BindStateChangedListener() {
            @Override
            public void onComponentBoundToWindow(Component component) {
                createShadow();
            }

            @Override
            public void onComponentUnboundFromWindow(Component component) {

            }
        });
        this.setArrangeListener(new ArrangeListener() {
            @Override
            public boolean onArrange(int left, int top, int width, int height) {
                return false;
            }
        });
    }

    private void initPadding() {
        int xPadding = shadowRadius + Math.abs(shadowOffsetX);
        int yPadding = shadowRadius + Math.abs(shadowOffsetY);
        setPadding(xPadding, yPadding, xPadding, yPadding);
    }

    private void createShadow() {
        if (shadowEffect) {
            PixelMap shadowBitmap = createShadowBitmap();
            if (shadowBitmap == null) return;
            PixelMapElement shadowDrawable = new PixelMapElement(shadowBitmap);
            setBackground(shadowDrawable);
        } else {
            clearShadow();
        }
    }

    private PixelMap createShadowBitmap() {
        PixelMap shadowBitmap;
        if (getWidth() > 0 && getHeight() > 0) {
            PixelMap.InitializationOptions options = new PixelMap.InitializationOptions();
            options.size = new Size(getWidth(), getHeight());
            options.pixelFormat = PixelFormat.ARGB_8888;
            shadowBitmap = PixelMap.create(options);
        } else {
            return null;
        }
        Texture texture = new Texture(shadowBitmap);
        Canvas canvas = new Canvas(texture);
        RectFloat shadowRect = new RectFloat(
                shadowRadius + Math.abs(shadowOffsetX),
                shadowRadius + Math.abs(shadowOffsetY),
                getWidth() - shadowRadius - Math.abs(shadowOffsetX),
                getHeight() - shadowRadius - Math.abs(shadowOffsetY));
        Paint shadowPaint = new Paint();
        shadowPaint.setAntiAlias(true);
        shadowPaint.setColor(Color.BLUE);
        shadowPaint.setStyle(Paint.Style.FILL_STYLE);
//        if (!isInEditMode()) {
//            shadowPaint.setShadowLayer(shadowRadius, shadowOffsetX, shadowOffsetY, shadowColor);
//        }
        canvas.drawRoundRect(shadowRect, shadowCornerRadius, shadowCornerRadius, shadowPaint);
        return shadowBitmap;
    }

    /**
     * set ShadowOffsetX
     * @param newShadowOffsetX
     */
    public void setShadowOffsetX(int newShadowOffsetX) {
        this.shadowOffsetX = newShadowOffsetX;
        initPadding();
    }

    /**
     * set ShadowOffsetY
     * @param newShadowOffsetY
     */
    public void setShadowOffsetY(int newShadowOffsetY) {
        this.shadowOffsetY = newShadowOffsetY;
        initPadding();
    }

    /**
     * set ShadowRadius
     * @param newShadowRadius
     */
    public void setShadowRadius(int newShadowRadius) {
        this.shadowRadius = newShadowRadius;
        initPadding();
    }

    /**
     * set ShadowCornerRadius
     * @param newShadowCornerRadius
     */
    public void setShadowCornerRadius(int newShadowCornerRadius) {
        this.shadowCornerRadius = newShadowCornerRadius;
        initPadding();
    }

    /**
     * set ShadowColor
     * @param newShadowColor
     */
    public void setShadowColor(Color newShadowColor) {
        this.shadowColor = newShadowColor;
    }

    /**
     * set ShadowEffect
     * @param newShadowEffect
     */
    public void setShadowEffect(boolean newShadowEffect) {
        this.shadowEffect = newShadowEffect;
    }

    /**
     * clear Shadow
     */
    public void clearShadow() {
        Util.setDrawable(this, null);
    }
}
